'''
Created on Sep 7, 2011

@author: TommySprat
'''

#DEBUG KEY (NEXTLEVEL) = SLASH

#import necessary modules
import sys
import os
import pygame
from pygame.locals import * #@UnusedWildImport
import socket
from AnimationSystem import AnimationSystem, load_images #@UnresolvedImport
import random


#Set up Pygame
pygame.init()
mainClock = pygame.time.Clock()

#Initialize all variables and constants

VERSION = "Release 1.0"


BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (228, 236, 0) # #E4EC00
WHITE = (255, 255, 255)
GREY = (162, 154, 141)
TARGET_RESOLUTION = (1280, 720)
RESOLUTION = None

#event lists
keydownList = []
keyupList = []
mousebuttondownList = []
mousebuttonupList = []

FPS = 30
updateQueue = [] #Contains references to objects that update during every frame
gameState = "lobby" # "loading" "Platformer" "frogger" "gamewon"
soupComponents = []
waterBubbles = []
frgObstacles = []
pltPlates = []
soupFill = None
waterFill = None
frgCore = None
pltCore = None
gameWonCore = None
animationSystem = AnimationSystem()
pltOverlayClock = 255
frgCharacter = None
pltCharacter = None

arial = pygame.font.SysFont("arial", 40)
arialWin = pygame.font.SysFont("arial", 72, 1)


#Set up the window
for res in pygame.display.list_modes(): #see if the target resolution is available
    if res == TARGET_RESOLUTION:
        RESOLUTION = res

if RESOLUTION == None:
    print "\n\n"+"ERROR: Resolution " + str(TARGET_RESOLUTION) + " not found."+"\n\n"
    sys.exit(1) #exit with error code 1

#Initialize the visual things
os.environ['SDL_VIDEO_WINDOW_POS'] = '43,10' #set the window starting position
windowSurface = pygame.display.set_mode(RESOLUTION, 0, 32)
frgObstacleSprites = load_images(["Data/Fork0.png", "Data/Knife0.png"])
waterBubbleSprite = load_images(['Data/WaterBubble.png'])[0]
pygame.display.set_caption('Expo Team43 game ' + VERSION)

#Set up some graphic constants here
frgHurt = pygame.Surface((1280, 720)) #Frogger hurt effect surface
pltHurt = pygame.Surface((1280, 720)) #Platformer hurt effect surface
winMSG = arialWin.render("Player 1 wins!!", 1, YELLOW, GREY)
winMSG2 = arial.render("Press Enter", 1, RED, GREY)
frgExitsign = load_images(["Data/FrgExitsign.png"])[0]
frgExit = load_images(["Data/Exit.png"])[0]
pltExit = pygame.transform.flip(load_images(["Data/Exit.png"])[0], 1, 0) 
iTopiaLogo = load_images(["Data/ITopia160.gif"])[0]

#LOBBY OBJECTS
class Lobby:
    def __init__(self):
        self.sprite = load_images(["Data/lobby.png"], 1)[0]
        self.redX = load_images(["Data/RedX.png"])[0]
        self.checkmark = load_images(["Data/Checkmark.png"])[0]
        self.readyButton = load_images(["Data/ReadyButton.png"])[0]
        self.playerOneClipboardName = arial.render("Player One", 1, BLACK, pygame.Color("#f8f8fa"))
        self.playerOneReady = False
        self.playerOneStatus = self.redX
        mousebuttondownList.append(self)
        updateQueue.append(self)
        keydownList.append(self)
        self.readyButtonPosition = pygame.Rect(195, 580, 142, 57)
        self.transitionDelayCounter = 0 #delay the soupFill 1 second so that the checkmark can appear
                                        #otherwise it won't blit the change and you'd never see the checkmark
        
    def clickCheck(self, pos):
        if self.readyButtonPosition.collidepoint(pos):
            if self.playerOneReady == 0:
                self.playerOneReady = 1
                self.playerOneStatus = self.checkmark
            print "TROLOLO! :D"
            
    #Leave the lobby and start the games :D
    def startGame(self):
        global soupFill
        global gameState
        
        global lobby
        lobby = None
        mousebuttondownList.remove(self)
        updateQueue.remove(self)
        keydownList.remove(self)
        
        soupFill = SoupFill(endLoadingFrg)
        gameState = "loading"
    
    def update(self):
        if self.playerOneReady:
            self.transitionDelayCounter += 1
        if self.transitionDelayCounter == FPS:
            self.startGame()
            
    def keydownCheck(self, key):
        if key == pygame.K_SLASH:
            self.startGame()
    
    def __del__(self):
        print "Lobby instance deleted"
            
#LOADING OBJECTS
class SoupFill:
    def __init__(self, whenDone):
        animationSystem.init(self)
        updateQueue.append(self)
        self.whenDone = whenDone
        self.position = pygame.rect.Rect(0, 720, 1280, 200)
        self.bottomSoupRect = pygame.rect.Rect(0, 720, 1280, 0)
        self.spriteList = load_images(['Data/SoupTop1.png', 'Data/SoupTop2,4.png',
                               'Data/SoupTop3.png'])
        
    def update(self):
        animationSystem.framestep(self, FPS/7, 1)
        self.position.move_ip(random.uniform(-25,25), -(FPS/6)) #FPS/6 for good speed
        if self.position.left > 1024:
            self.position.left = 0
        self.bottomSoupRect.top = self.position.bottom
        self.bottomSoupRect.height = 720-self.position.bottom
        if random.random() > 0.84: #spawn meatballs randomly
            Meatball()
        if self.position.bottom < -400: #Stop "loading" when the soup has filled the screen
            self.whenDone()
            
    def __del__(self):
        print "SoupFill instance deleted"
        
class Meatball:
    def __init__(self):
        self.speed = random.uniform(0,4)
        soupComponents.append(self)
        updateQueue.append(self)
        self.position = pygame.Rect(random.uniform(0, 1280), 820, 100, 100)
        self.sprite = load_images(['Data/Meatball.png'])[0]
        
        
    def update(self):
               
        self.position.move_ip(0, -self.speed)
        if self.position.bottom < -10 or gameState != "loading":
            updateQueue.remove(self)
            soupComponents.remove(self)
        
    def __del__(self):
        #print "Meatball "+repr(self)+ " out"
        pass

#STATE CHANGE METHODS
def endLoadingFrg():
    global gameState
    global soupFill
    updateQueue.remove(soupFill)
    soupFill = None
    gameState = "frogger"
    global frgCharacter
    global frgCore
    frgCharacter = FrgCharacter()
    frgCore = FrgCore()
    
def endLoadingPlt():
    global gameState
    global soupFill
    try:
        updateQueue.remove(soupFill)
    except ValueError:
        pass #if there is no soupFill just ignore this statement
    soupFill = None
    gameState = "platformer"
    global pltCharacter
    global pltCore
    global waterFill
    pltCharacter = PltCharacter()
    pltCore = PltCore()
    waterFill = WaterFill()
    
def endLoadingWinner():
    global gameWonCore
    
    gameWonCore = GameWonCore()

#FROGGER OBJECTS
class FrgCharacter:
    def __init__(self):
        animationSystem.init(self)
        self.spriteList = load_images(["Data/CharLeft.png", "Data/CharRight.png"])
        self.sprite = self.spriteList[0]
        self.position = pygame.Rect(640, 640, 24, 64)
        self.visualposition =  pygame.Rect (0, 0, 64, 64)
        self.moveTarget = [0, 0] #topleft x and y to travel to
        self.moving = 0
        self.speed = 6.4 #10 ticks to move 64 pixels
        self.clock = 0 #when you move clock starts counting and at 10 you get set to moveTarget
        self.hurt = 0
        self.overlayClock = 255 #The alpha value for the red overlay, only draws when hurt
        updateQueue.append(self)
        keydownList.append(self)
        
    def keydownCheck(self, key):
        if (key == K_w or key == K_UP) and self.moving == 0:
            if self.position.top >= 64:
                animationSystem.framestep(self, 1, 1)
                self.moving = "up"
                self.moveTarget[0] = self.position.left
                self.moveTarget[1] = self.position.top-64
        if (key == K_a or key == K_LEFT) and self.moving == 0:
            if self.position.left >= 64:
                animationSystem.framestep(self, 1, 1)
                self.moving = "left"
                self.moveTarget[0] = self.position.left-64
                self.moveTarget[1] = self.position.top
        if (key == K_s or key == K_DOWN) and self.moving == 0:
            if self.position.bottom <= 720-64:
                animationSystem.framestep(self, 1, 1)
                self.moving = "down"
                self.moveTarget[0] = self.position.left
                self.moveTarget[1] = self.position.top+64
        if (key == K_d or key == K_RIGHT) and self.moving == 0:
            if self.position.right <= 1280-64:
                animationSystem.framestep(self, 1, 1)
                self.moving = "right"
                self.moveTarget[0] = self.position.left+64
                self.moveTarget[1] = self.position.top
                    
    def update(self):
        
        self.visualposition.left = self.position.left-20
        self.visualposition.top = self.position.top
        
        if self.moving != 0:
            if self.moving == "up":
                self.position.move_ip(0, -self.speed)
                self.clock +=1
            if self.moving == "left":
                self.position.move_ip(-self.speed, 0)
                self.clock +=1
            if self.moving == "down":
                self.position.move_ip(0, self.speed)
                self.clock +=1
            if self.moving == "right":
                self.position.move_ip(self.speed, 0)
                self.clock +=1
        if self.clock == 10:
            self.position.left = self.moveTarget[0]
            self.position.top = self.moveTarget[1]
            self.clock = 0
            self.moving = 0
        
        if self.hurt:
            self.overlayClock -= 3 #Make the red overlay fade
            if self.overlayClock <= 64:
                self.hurt = 0
                self.overlayClock = 255

        #Collision checking with all obstacles        
        for obstacle in frgObstacles:
            if self.position.colliderect(obstacle.position):
                self.moving = 0
                self.clock = 0
                self.hurt = 1
                self.position.left = 640
                self.position.top = 640
                
        #When you reach the exit
        if (self.position.top >= 64 and self.position.top <= 192 and self.position.left < 64):
            self.nextLevel()
            
        if gameState != "frogger":
            global frgCharacter #These if statements must be split or it will give a syntaxwarning
            if frgCharacter == self:
                #global frgCharacter
            
                updateQueue.remove(self)
                keydownList.remove(self)
                frgCharacter = None        
        
    def nextLevel(self):
            global soupFill
            global gameState
            global frgCharacter

            frgCharacter = None
            updateQueue.remove(self)
            keydownList.remove(self) 
            
            soupFill = SoupFill(endLoadingPlt)
            gameState = "loading"
            
    def __del__(self):
        print "frgCharacter instance deleted"


class FrgCore:
    def __init__(self):
        updateQueue.append(self)
        keyupList.append(self)
        self.sprite = load_images(["Data/FrgBackground.jpg"], 0)[0]
        self.clock = 0
        self.obstacleIndex = 0 #6 bottom rows to spawn obstacles on
        self.bottomRowsDirections = [1, 0, 0, 1, 0, 1]#0 is facing left
        self.obstacleRows = []
        for i in range(6):
            self.obstacleRows.append(self.getObstaclePattern())
        
        #fill the field with obstacles before the game starts
        for row in range(6):
            rowPattern = []
            for i in range(4): #build a list of 20 elements, 4*5
                rowPattern.extend(self.getObstaclePattern())
                if i == 3: #when the list is complete, spawn obstacles from it
                    for obstacleN in range(len(rowPattern)):
                        if rowPattern[obstacleN]:
                            FrgObstacle(3+row, self.bottomRowsDirections[row], obstacleN)
                        
    def update(self):
        self.clock += 1
        if self.clock == 32: #speed of 2 means distance of 64 per 32 ticks
            self.clock = 0
            if self.obstacleIndex == 6:#reset patterns when out of obstacles
                self.obstacleIndex = 0
                self.obstacleRows = []
                for i in range(6):
                    self.obstacleRows.append(self.getObstaclePattern())
            row = 3 #row is the actual on screen row where the obstacles go
            i = 0 # i = 0 is the first row with obstacles
            for pattern in self.obstacleRows:
                if pattern[0]:
                    FrgObstacle(row, self.bottomRowsDirections[i])
                i += 1
                row += 1
                pattern.pop(0)
            self.obstacleIndex += 1
            
        if gameState != "frogger":
            global frgCore
            
            updateQueue.remove(self)
            keyupList.remove(self)
            frgCore = None
            
    def __del__(self):
        print "FrgCore instance deleted"
    
    def keyupCheck(self, key):
        if key == K_SLASH:
            global soupFill
            global gameState
            global frgCore

            updateQueue.remove(self)
            keyupList.remove(self)
            frgCore = None 
            
            soupFill = SoupFill(endLoadingPlt)
            gameState = "loading"
            
    def getObstaclePattern(self):
        '''Returns a list with 5 elements that are either 0 or 1'''
        pattern = [0, random.randint(0,1), 0, random.randint(0,1), 0, random.randint(0,1)]
        return pattern

class FrgObstacle:
    def __init__(self, row, direction, column=0):
        self.direction = direction #0 is facing left
        self.spriteList = frgObstacleSprites
        self.sprite = self.spriteList[random.randint(0,1)]
        self.sprite = pygame.transform.flip(self.sprite, self.direction, 0)
        self.row = row
        updateQueue.append(self)
        frgObstacles.append(self)
        self.speed = 2
        
        if self.direction:
            self.position = pygame.Rect(-64+column*64, 24 + 64*row, 64, 16)
        else:
            self.position = pygame.Rect(1344-column*64, 24 + 64*row, 64, 16)
    
    def update(self):
        if self.direction:
            self.position.move_ip(self.speed, 0)
        else:
            self.position.move_ip(-self.speed, 0)
        if self.position.right < -100 or self.position.left > 1380:
            updateQueue.remove(self)
            frgObstacles.remove(self)
            
    def __del__(self):
        #print "Obstacle deleted"
        pass

# PLATFORMER OBJECTS
class PltCharacter:
    def __init__(self):
        updateQueue.append(self)
        keydownList.append(self)
        keyupList.append(self)
        self.spriteList = load_images(["Data/Charleft.png", "Data/CharRight.png"])
        self.sprite = self.spriteList[0]
        self.position = pygame.Rect(1216, 576, 64, 64) #Where the sprite is drawn
        self.body = pygame.Rect(0, 0, 40, 4) #Where collisions are checked
        self.movingLeft = self.movingRight = 0
        self.movingLeftBuffer = self.movingRightBuffer = 0
        self.speed = 4.8
        self.jumping = 0
        self.falling = 1
        self.vspeed = 0
        self.jumpspeed = -16
        self.jumpguard = 0 #allow escaping from a collision when jumping
        
    def update(self):
        global pltOverlayClock
        
        self.body.left = self.position.left + 12
        self.body.bottom = self.position.bottom
        if self.movingLeft and self.position.left > self.speed:
            self.position.move_ip(-self.speed, 0)
            
        if self.movingRight and self.position.right < 1280-self.speed:
            self.position.move_ip(self.speed, 0)
            
        if self.falling or self.jumping:
            self.position.move_ip(0, self.vspeed)
            if self.falling:
                self.vspeed += 2
                
        if self.vspeed >8:
            self.vspeed =8
            
        if self.jumpguard == 0:
            self.falling = 1
            for plate in pltPlates:
                if self.body.colliderect(plate.body):
                    self.falling = 0
                    self.jumping = 0
                    self.vspeed = 0
                      
        if self.jumpguard > 0:
            self.jumpguard -= 1
        
        if self.position.bottom < 540 and self.position.left < 500 and waterFill.rising == 0:
            waterFill.rising = 1 #let the water rise when you are far enough
            print "The boiling water starts rising."
        
        #End this level when you reach the exit    
        if (self.position.top <= 128 and self.position.right > 1240): 
            self.nextLevel()
            
        if (self.position.bottom > waterFill.position.top + 100):
            #global pltOverlayClock
            pltOverlayClock -= 3
            self.restartLevel()
            
        if pltOverlayClock < 255:
            pltOverlayClock -= 3
            if pltOverlayClock <= 0:
                pltOverlayClock = 255 
    
    def keydownCheck(self, key):
        if key == K_a or key == K_LEFT:
            if self.movingRight == 0:
                self.movingLeft = 1
                self.sprite = self.spriteList[0]
            else:
                self.movingLeftBuffer = 1
        if key == K_d or key == K_RIGHT:
            if self.movingLeft == 0:
                self.movingRight = 1
                self.sprite = self.spriteList[1]
            else:
                self.movingRightBuffer = 1
        if key == K_w or key == K_SPACE or key == K_UP:            
            if self.jumping != 1:
                self.vspeed -= 13
                self.jumping = 1
                self.jumpguard = 9
                
        if key == K_SLASH:
            self.nextLevel()
    
    def keyupCheck(self, key):
        if key == K_a or key == K_LEFT:
            self.movingLeft = self.movingLeftBuffer = 0
            if self.movingRightBuffer:
                self.movingRight = 1
                self.sprite = self.spriteList[1]
            
        if key == K_d or key == K_RIGHT:
            self.movingRight = self.movingRightBuffer = 0
            if self.movingLeftBuffer:
                self.movingLeft = 1
                self.sprite = self.spriteList[0]         
                
    def restartLevel(self):
        global soupFill
        global gameState
        global pltCharacter

        pltCharacter = None
        updateQueue.remove(self)
        keydownList.remove(self) 
        
        endLoadingPlt()
        
    def nextLevel(self):
        global gameState
        global pltCharacter

        pltCharacter = None
        updateQueue.remove(self)
        keydownList.remove(self) 
        
        gameState = "gamewon"
        endLoadingWinner()
            
    def __del__(self):
        print "pltCharacter instance deleted"  
    
class PltCore:
    def __init__(self):
        updateQueue.append(self)
        self.sprite = load_images(["Data/PltBackground.jpg"], 0)[0]
        
        self.plateGrid = [ # [row][column]
                          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                          [0, 0, 1, 0, 0, 0, 0, 0, 1, 1],
                          [1, 0, 0, 0, 1, 0, 1, 0, 0, 0],
                          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                          [0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
                          [0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
                          [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                          [0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
                          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                          [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
                         ]
                                                 
        for row in range(len(self.plateGrid)):
            for column in range(len(self.plateGrid[row])):
                if self.plateGrid[row][column]:
                    PltPlate(column*128, row*64)
    def update(self):
        if gameState != "platformer":
            global pltCore
            pltCore = None
            
            updateQueue.remove(self)
    
    def __del__(self):
        print "PltCore instance deleted"

class PltPlate:
    def __init__(self, xpos, ypos):
        pltPlates.append(self)
        self.position = pygame.Rect(xpos, ypos, 128, 38)
        self.body = pygame.Rect(self.position.left, self.position.top+19, 128, 19)
        self.sprite = load_images(["Data/PltPlate.png"])[0]
        
class WaterFill:
    def __init__(self):
        animationSystem.init(self)
        updateQueue.append(self)
        self.riseCounter = 0 # Don't rise every frame with small amounts it glitches.
                            # Rise every few frames with a "big" amount instead
        self.rising = 0 #only start rising when the player is far enough
        self.position = pygame.rect.Rect(0, 590, 1280, 200)
        self.bottomWaterRect = pygame.rect.Rect(0, 720, 1280, 0)
        self.spriteList = load_images(['Data/WaterTop1.png', 'Data/WaterTop2,4.png',
                               'Data/WaterTop3.png'])
                
    def update(self):
        if gameState != "platformer":
            global waterFill
            waterFill = None
            updateQueue.remove(self)
        
            
        self.riseCounter += 1
        if self.riseCounter == 3:
            self.riseCounter = 0
            animationSystem.framestep(self, FPS/18, 1)
            if self.rising:
                self.position.move_ip(random.uniform(-25,25), -3)
            if self.position.left > 1024:
                self.position.left = 0
            self.bottomWaterRect.top = self.position.bottom
            self.bottomWaterRect.height = 720-self.position.bottom
        if random.random() > 0.5: #Random bubbles :D
            WaterBubble()

            
    def __del__(self):
        print "WaterFill instance deleted"
        
class WaterBubble:
    def __init__(self):
        self.speed = random.uniform(9,18)
        waterBubbles.append(self)
        updateQueue.append(self)
        self.position = pygame.Rect(random.uniform(-64, 1280), 820, 100, 100)
        self.sprite = waterBubbleSprite
        
        
    def update(self):
               
        self.position.move_ip(0, -self.speed)
        if gameState != "platformer":
            updateQueue.remove(self)
            waterBubbles.remove(self)
            
        try:
            if self.position.top < waterFill.position.top+100:
                updateQueue.remove(self)
                waterBubbles.remove(self)
        except AttributeError:
            #waterFill will be deleted and the first if statement will have deleted this bubble
            pass
                    
    def __del__(self):
        #print "WaterBubble "+repr(self)+ " out"
        pass
    
class GameWonCore:
    def __init__(self):
        updateQueue.append(self)
        keyupList.append(self)
        animationSystem.init(self)
        self.position = pygame.Rect(285, 5, 0, 0)
        self.spriteList = load_images(["Data/GameWonBanana0.png", "Data/GameWonBanana1.png", "Data/GameWonBanana3.png",
                                       "Data/GameWonBanana4.png", "Data/GameWonBanana5.png", "Data/GameWonBanana6.png",
                                       "Data/GameWonBanana7.png"])
        
    def update(self):
        animationSystem.framestep(self, FPS/8, 1)
        
    def keyupCheck(self, key):
        if key == K_RETURN:
            pygame.event.post(pygame.event.Event(pygame.QUIT))
    
    def __del__(self):
        print "GameWonCore instance deleted"
        
def notifyExpo43GameServer():
    '''Notifies the Expo43 GameServer that this ExpoGame has finished and will now close.
    It listens on port 4447 on the same machine. You only need to connect to it briefly'''
    try:
        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('127.0.0.1', 4447))
        print "Connection to Expo43GameServer made"
        s.close()
        print "Connection to Expo43GameServer closed"
    except socket.error:
        print "Expo43GameServer not found, moving on without notifying"

#Game starts here
lobby = Lobby()
#gameState = "gamewon"
#endLoadingWinner()

while True:

    #Update all objects       
    for instance in updateQueue:
        instance.update()
    
    #Event handling goes here
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            notifyExpo43GameServer()
            pygame.quit()
            sys.exit()
        if event.type == MOUSEBUTTONDOWN:
            for instance in mousebuttondownList:
                instance.clickCheck(event.pos)
        if event.type == KEYUP:
            for instance in keyupList:
                instance.keyupCheck(event.key)
        if event.type == KEYDOWN:
            for instance in keydownList:
                instance.keydownCheck(event.key)
    
    #Possible gamestates: lobby, loading, platformer, frogger, gamewon.
    
    if gameState == "lobby":        
        
        windowSurface.blit(lobby.sprite, (0,0))
        windowSurface.blit(lobby.playerOneStatus, (350,270))    
        windowSurface.blit(lobby.readyButton, lobby.readyButtonPosition)       
        windowSurface.blit(lobby.playerOneClipboardName, (130, 270))
                                
    if gameState == "loading":
        windowSurface.blit(soupFill.sprite, soupFill.position)
        windowSurface.blit(soupFill.sprite, (soupFill.position.left-1280,soupFill.position.top))
        windowSurface.blit(soupFill.sprite, (soupFill.position.right,soupFill.position.top))
        pygame.draw.rect(windowSurface, pygame.Color('#ed3200'), soupFill.bottomSoupRect)
        for component in soupComponents:
            windowSurface.blit(component.sprite, component.position)
            
    if gameState == "frogger":
        windowSurface.blit(frgCore.sprite, (0,0))
        windowSurface.blit(frgExitsign, (512,0))
        windowSurface.blit(frgExit, (0, 64))
        
        windowSurface.blit(frgCharacter.sprite, frgCharacter.visualposition)
        #pygame.draw.rect(windowSurface, RED, frgCharacter.position)
        
        for obstacle in frgObstacles:
            windowSurface.blit(obstacle.sprite, obstacle.position)
            
        if frgCharacter.hurt:
            frgHurt.set_alpha(frgCharacter.overlayClock)
            frgHurt.fill(RED)
            windowSurface.blit(frgHurt, (0, 0))
            
    if gameState == "platformer":
        #windowSurface.fill(GREY)
        windowSurface.blit(pltCore.sprite, (0,0))
        #windowSurface.blit(platformerMSG, (130, 270))
        windowSurface.blit(pltExit, (1216, 0))
        
        for plate in pltPlates:
            windowSurface.blit(plate.sprite, plate.position)
            #pygame.draw.rect(windowSurface, BLUE, plate.body) Bounding Boxes
            
        windowSurface.blit(pltCharacter.sprite, pltCharacter.position)
        #pygame.draw.rect(windowSurface, RED, pltCharacter.body, 0) Bounding Box
        
        windowSurface.blit(waterFill.sprite, waterFill.position)
        windowSurface.blit(waterFill.sprite, (waterFill.position.left-1280,waterFill.position.top))
        windowSurface.blit(waterFill.sprite, (waterFill.position.right,waterFill.position.top))
        pygame.draw.rect(windowSurface, pygame.Color('#2d76ff'), waterFill.bottomWaterRect)
        for bubble in waterBubbles:
            windowSurface.blit(bubble.sprite, bubble.position)
            
        if pltOverlayClock < 255:
            pltHurt.set_alpha(pltOverlayClock)
            pltHurt.fill(BLUE)
            windowSurface.blit(pltHurt, (0, 0))
            
    if gameState == "gamewon":
        windowSurface.fill(GREY)
        
        windowSurface.blit(gameWonCore.sprite, gameWonCore.position)
        
        windowSurface.blit(winMSG, (10, 10))
        windowSurface.blit(winMSG2, (860, 570))
        windowSurface.blit(iTopiaLogo, (40, 100))
    
    pygame.display.update() 
    mainClock.tick(FPS)
    pygame.display.set_caption('Expo Team43 game ' + VERSION + "      FPS: " +
                               str(round(mainClock.get_fps())))

